package com.zhichat.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.zhichat.infrastructure.interceptor.ServerAccessInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @ClassName: ZhiChatWebMvcConfig
 * @Description: 配置类
 * @Author: 团长九哥 https://space.bilibili.com/602197686
 * @CreateDate: 2024/11/01 22:42
 */
@Configuration
public class ZhiChatWebMvcConfig extends WebMvcConfigurationSupport {

    @Autowired
    private ServerAccessInterceptor serverAccessInterceptor;

    /**
     * 添加拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(serverAccessInterceptor)
                .addPathPatterns("/**") // 拦截所有请求（走serverAccessInterceptor拦截器逻辑）
                .excludePathPatterns("/doc.html"            // 排除swagger页面
                        , "/swagger-resources/**"           // Swagger 资源
                        , "/swagger-ui.html"                // Swagger UI 页面
                        , "/webjars/**"                     // Swagger 资源
                        , "/v2/api-docs"                    // API 文档数据
                        , "/error"                          // 放行错误路径
                        , "/message/sendFileSucCallback"    // 放行文件上传成功回调接口
                        , "/assist/t1"
                        , "/assist/t3"
                        , "/message/downloadFile1"
                        , "/user/resMsg"
                        , "/assist/t2") // 放行的接口路径
        ;
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 放行静态资源
        registry.addResourceHandler("/swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
        super.addResourceHandlers(registry);
    }

    /**
     * 设置字符编码和日期格式
     *
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
            }
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                ((MappingJackson2HttpMessageConverter) converter).setObjectMapper(new JacksonObjectMapper()); // 处理 LocalDateTime、LocalDate、LocalTime 日期格式
//                ((MappingJackson2HttpMessageConverter) converter).getObjectMapper().setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); // 处理 Date 日期格式
            }
        }
    }

    private static class JacksonObjectMapper extends ObjectMapper {
        public JacksonObjectMapper() {
            super();
            SimpleModule simpleModule = new SimpleModule()
                    .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                    .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
                    .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")))
                    .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                    .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
                    .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
            this.registerModule(simpleModule);
        }
    }
}
